package vwg.na.vwm.rh.motorsdk.commons.entidades;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;

import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

import vwg.na.vwm.rh.motorsdk.modelo.procesos.PerArmonizadoArmonizadorProceso;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.PerEmpleadoCCProceso;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.PerEmpleadoCMProceso;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.PerEmpleadoEP3CC1Proceso;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.PerEmpleadoFBProceso;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.PerEmpleadoFMProceso;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.PerEvaluadoEvaluadorProceso;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.PerEvaluadoProceso;
import vwg.na.vwm.rh.motorsdk.modelo.procesos.entidadesgrales.DevObservador;
import vwg.na.vwm.rh.rhmotor.modelo.entidad.Pendiente;
import vwg.na.vwm.rh.rhmotor.modelo.entidad.PersonaPendiente;
import vwg.na.vwm.rh.rhmotor.modelo.entidad.RolPersona;

@Entity
@Table(name = "persona")
public class Persona implements Serializable {

	private static final long serialVersionUID = 1L;

	public static final char ACTIVO = 1;
	public static final char INACTIVO = 0;

	private Integer persona;
	private String paterno;
	private String materno;
	private String nombre;
	private Persona jefe;
	private Calendar registradoFecha;
	private Calendar actualizadoFecha;
	private char personaActivo;

	private boolean esJefe;
	private String usuarioRed;
	private String nombreCompleto;

	private RolPersona rolesPersona;
	private EstadoCivil estadoCivil;
	private List<Pendiente> pendientes;
	private Remuneracion remuneracion;
	private DatosPersonales datosPersonales;
	private DatosFecha datosFecha;
	private EstructuraPersonal estructuraPersonal;

	private EstructuraEmpresa estructuraEmpresa;

	private List<PersonaPendiente> personaPendientes;

	private List<DevObservador> observadores;

	public Persona() {
		pendientes = new ArrayList<>();
		personaPendientes = new ArrayList<PersonaPendiente>();
		datosFecha = new DatosFecha();
	}

	public Persona(String paterno, String materno, String nombre, Persona jefe,
			Calendar registradoFecha, Calendar actualizadoFecha,
			char personaActivo) {
		this();
		this.paterno = paterno;
		this.materno = materno;
		this.nombre = nombre;
		this.jefe = jefe;
		this.registradoFecha = registradoFecha;
		this.actualizadoFecha = actualizadoFecha;
		this.personaActivo = personaActivo;
	}

	@Id
	@Column
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Integer getPersona() {
		return persona;
	}

	public void setPersona(Integer persona) {
		this.persona = persona;
	}

	@Column(insertable = false, updatable = false)
	public String getPaterno() {
		return paterno;
	}

	public void setPaterno(String paterno) {
		this.paterno = paterno;
	}

	@Column(insertable = false, updatable = false)
	public String getMaterno() {
		return materno;
	}

	public void setMaterno(String materno) {
		this.materno = materno;
	}

	@Column(insertable = false, updatable = false)
	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	@Version
	@Temporal(TemporalType.TIMESTAMP)
	public Calendar getRegistradoFecha() {
		return registradoFecha;
	}

	public void setRegistradoFecha(Calendar registradoFecha) {
		this.registradoFecha = registradoFecha;
	}

	@Version
	@Temporal(TemporalType.TIMESTAMP)
	public Calendar getActualizadoFecha() {
		return actualizadoFecha;
	}

	public void setActualizadoFecha(Calendar actualizadoFecha) {
		this.actualizadoFecha = actualizadoFecha;
	}

	@Column(insertable = false, updatable = false)
	public char getPersonaActivo() {
		return personaActivo;
	}

	public void setPersonaActivo(char personaActivo) {
		this.personaActivo = personaActivo;
	}

	@Transient
	public boolean isEsJefe() {
		return esJefe;
	}

	public void setEsJefe(boolean esJefe) {
		this.esJefe = esJefe;
	}

	@Transient
	public String getUsuarioRed() {
		return usuarioRed;
	}

	public void setUsuarioRed(String usuarioRed) {
		this.usuarioRed = usuarioRed;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "jefe")
	public Persona getJefe() {
		return jefe;
	}

	public void setJefe(Persona jefe) {
		this.jefe = jefe;
	}

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "persona")
	public RolPersona getRolesPersona() {
		return rolesPersona;
	}

	public void setRolesPersona(RolPersona rolesPersona) {
		this.rolesPersona = rolesPersona;
	}

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "persona")
	public EstructuraPersonal getEstructuraPersonal() {
		return estructuraPersonal;
	}

	public void setEstructuraPersonal(EstructuraPersonal estructuraPersonal) {
		this.estructuraPersonal = estructuraPersonal;
	}

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "persona")
	public EstructuraEmpresa getEstructuraEmpresa() {
		return estructuraEmpresa;
	}

	public void setEstructuraEmpresa(
			EstructuraEmpresa personaEstructurasEmpresas) {
		this.estructuraEmpresa = personaEstructurasEmpresas;
	}

	@LazyCollection(LazyCollectionOption.FALSE)
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "personaAplica")
	public List<Pendiente> getPendientes() {
		return pendientes;
	}

	public void setPendientes(List<Pendiente> pendientes) {
		this.pendientes = pendientes;
	}

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JoinColumn(name = "estadoCivil")
	public EstadoCivil getEstadoCivil() {
		return estadoCivil;
	}

	public void setEstadoCivil(EstadoCivil estadoCivil) {
		this.estadoCivil = estadoCivil;
	}

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "persona")
	public Remuneracion getRemuneracion() {
		return remuneracion;
	}

	public void setRemuneracion(Remuneracion remuneracion) {
		this.remuneracion = remuneracion;
	}

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "persona")
	public DatosPersonales getDatosPersonales() {
		return datosPersonales;
	}

	public void setDatosPersonales(DatosPersonales datosPersonales) {
		this.datosPersonales = datosPersonales;
	}

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "persona")
	public DatosFecha getDatosFecha() {
		return datosFecha;
	}

	public void setDatosFecha(DatosFecha datosFecha) {
		this.datosFecha = datosFecha;
	}


	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "personaAtiende")
	public List<PersonaPendiente> getPersonaPendientes() {
		return personaPendientes;
	}

	public void setPersonaPendientes(List<PersonaPendiente> personaPendientes) {
		this.personaPendientes = personaPendientes;
	}

	@Transient
	public String getNombreCompleto() {
		nombreCompleto = this.nombre != null ? this.nombre + " " : ""
				+ this.paterno != null ? this.paterno + " "
				: "" + this.materno != null ? this.materno : "";
		return nombreCompleto;
	}

	public void setNombreCompleto(String nombreCompleto) {
		this.nombreCompleto = nombreCompleto;
	}

}
